﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ListItemEditor.UI
{
    public class DataGridViewMultiSelectEditingControl : TextBox, IDataGridViewEditingControl
    {
        #region member variables
        private DataGridView dataGridView = null;
        private int rowIndex = 0;
        private bool valueChanged = false;
        private object data = null;
        #endregion

        #region constructor

        public DataGridViewMultiSelectEditingControl()
        {
            base.TabStop = false;
            this.ReadOnly = true;
        }

        #endregion

        #region overrides

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            HideCaret(this.Handle);
            this.Select(0, 0);
        }

        #endregion

        #region IDataGridViewEditingControl Members

        public DataGridView EditingControlDataGridView { get { return dataGridView; } set { dataGridView = value; } }
        public object EditingControlFormattedValue { get { return data; } set { data = value; } }
        public int EditingControlRowIndex { get { return rowIndex; } set { rowIndex = value; } }
        public bool EditingControlValueChanged { get { return valueChanged; } set { valueChanged = value; } }
        public Cursor EditingPanelCursor { get { return Cursors.Arrow; } }
        public bool RepositionEditingControlOnValueChange { get { return false; } }

        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            this.Font = dataGridViewCellStyle.Font;
            if (dataGridViewCellStyle.BackColor.A < 0xff)
            {
                Color color = Color.FromArgb(0xff, dataGridViewCellStyle.BackColor);
                this.BackColor = color;
                this.dataGridView.EditingPanel.BackColor = color;
            }
            else
            {
                this.BackColor = dataGridViewCellStyle.BackColor;
            }
            this.ForeColor = dataGridViewCellStyle.ForeColor;
        }

        public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey) 
        {
            return false;
        }

        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            return data;
        }

        public void PrepareEditingControlForEdit(bool selectAll)
        {
            this.data = this.dataGridView.CurrentCell.Value;

            if (this.dataGridView.CurrentCell.FormattedValue == null) this.Text = string.Empty;
            else this.Text = this.dataGridView.CurrentCell.FormattedValue.ToString();
        }

        #endregion

        #region internal

        internal void OnCellMouseClick(DataGridViewMultiSelectCell cell, Point location)
        {
            DataGridViewMultiSelectColumn column = cell.OwningColumn as DataGridViewMultiSelectColumn;
            if (column == null) return;

            Form parentForm = this.dataGridView.FindForm();
            if (parentForm == null) return;

            Size size = new Size(400, 300);

            List<object> selectedIDs;
            if (column.SelectedValuesTranslator != null) selectedIDs = column.SelectedValuesTranslator.ParseSelectedValues(cell.Value);
            else
            {
                string value = cell.Value == null ? string.Empty : cell.Value.ToString();
                if (string.IsNullOrEmpty(value)) selectedIDs = new List<object>();
                else selectedIDs = value.Split(',').Cast<object>().ToList();
            }

            DialogResult result = MultiSelectForm.ShowMultiSelect(parentForm, null, column.Choices, column.DisplayMember, column.ValueMember, ref selectedIDs, location, size, FormStartPosition.Manual);
            if (result != DialogResult.OK) return;

            if (column.SelectedValuesTranslator != null)
            {
                this.data = column.SelectedValuesTranslator.FormatSelectedValues(selectedIDs);
                object formatted = column.SelectedValuesTranslator.FormatDisplayValue(this.data);
                this.Text = formatted == null ? string.Empty : formatted.ToString();
            }
            else
            {
                this.data = string.Join(",", selectedIDs.Cast<string>().ToArray());
                this.Text = this.data.ToString();
            }

            this.NotifyDataGridViewOfValueChange();
        }

        #endregion

        #region private

        [DllImport("user32")]
        private static extern bool HideCaret(IntPtr hWnd); 

        private void NotifyDataGridViewOfValueChange()
        {
            this.valueChanged = true;
            this.dataGridView.NotifyCurrentCellDirty(true);
        }

        #endregion
    }
}